package core

import (
	"net"

	"github.com/gorilla/websocket"
)

type Viewer struct {
	conn *websocket.Conn
	vid  string
}

// Channel 通道
type Channel struct {
	Id             string `json:"id"`
	Code           string `json:"code"`
	Status         int    `json:"status"`
	IsControllable int    `json:"isControllable"` // 是否可控制,0不可控，1可控制
	viewers        []*Viewer
	pusher         net.Conn
}

// OnPushingData Pusher有流推送过来时
func (ch *Channel) OnPushingData(data []byte) {

	if len(ch.viewers) == 0 {
		// 流没有了消费者，则断开与pusher之间的连接，使其停止推流，并且结束当前goroutine
		G.Log.Errorf("Puser[%s][%s] has none viewers, will Closing !", ch.pusher.RemoteAddr().String(), ch.Code)
		//_ = ch.pusher.Close()
		// 将当前通道的push提供者置为空
		ch.pusher = nil
		return
	} else {
		// 否则将流推给每个前端浏览者viewer
		for _, viewer := range ch.viewers {
			err := viewer.conn.WriteMessage(websocket.BinaryMessage, data)
			if err != nil {
				ch.OnViewerLeaved(viewer, err)
			}
		}
	}
}

// OnViewerLeaved 推流给Viewer失败时的回调
func (ch *Channel) OnViewerLeaved(v *Viewer, err error) {
	// 如果推流给viewer失败，则认为viewer已经关闭
	G.Log.Infof("Viewer[%s] ch=[%s] leaved with error %v", v.conn.RemoteAddr(), ch.Code, err)
	// 从channel将对应的viewer删除
	var vIdx int = -1
	for i := 0; i < len(ch.viewers); i++ {
		if ch.viewers[i].vid == v.vid {
			vIdx = i
			break
		}
	}
	if vIdx > -1 {
		ch.viewers = append(ch.viewers[:vIdx], ch.viewers[vIdx+1:]...)
	}
	G.Log.Infof("Channel[%s] remain [%d] viewers", ch.Code, len(ch.viewers))
	if len(ch.viewers) == 0 {
		// 需要检测该viewer请求的通道是否还有其他viewer还在使用流
		// 如果该通道已经没有消费者了，就可以通知PusherManager关闭该通道的推流动作了
		dispatcher.SendSignal(ch, &Message{Sign: SIG_CLOS, Chan: ch.Code}, 1)
		ch.pusher = nil
	}
}
